package com.codefish.codefishseckill.controller;

import cn.hutool.core.lang.Validator;
import com.codefish.codefishseckill.entity.AuthUser;
import com.codefish.codefishseckill.service.MailService;
import com.codefish.codefishseckill.vo.RespBean;
import com.codefish.codefishseckill.vo.RespBeanFactory;
import com.wf.captcha.SpecCaptcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 处理一些静态资源请求（如验证码等等）
 *
 * @author codefish
 * @version 1.0
 * @date 2022/08/03 下午 02:06
 */
@Controller
@RequestMapping("/resource")
@Slf4j
public class ResourceController {
    public static final String CAPTCHA_REDIS_PREFIX = "captcha:seckill:";
    public static final String LOGIN_CAPTCHA_REDIS_PREFIX = "captcha:login:";
    public static final String LOGIN_CAPTCHA_LIMIT_REDIS_PREFIX = "captcha:limit:";
    public static final String CAPTCHA_COOKIE_KEY = "JSESSIONID";

    @Autowired
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    MailService mailService;
    @Autowired
    ExecutorService executorService;

    @GetMapping("/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) {
        AuthUser authUser = (AuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String token = authUser.getUsername();
        //构建验证码对象
        SpecCaptcha captcha = new SpecCaptcha(130, 48, 5);
        //验证码校验信息存入redis
        redisTemplate.opsForValue().set(CAPTCHA_REDIS_PREFIX + token, captcha.text(), 60, TimeUnit.SECONDS);
        //token写入cookie
        //    CookieUtil.setCookie(response, CAPTCHA_COOKIE_KEY, token, 60 * 1000, "/");
        //验证码图片二进制流写入response
        try (OutputStream out = response.getOutputStream()) {
            captcha.out(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/login/captcha")
    @ResponseBody
    public RespBean getLoginCaptcha(@RequestParam String key) {
        if (!Validator.isEmail(key)) {
            return RespBeanFactory.fail("[" + key + "]为空或不是邮箱格式不合法");
        }
        if (!canGetCaptcha(key)) {
            //申请验证码太频繁
            return RespBeanFactory.fail("验证码申请过于频繁,请1min后再试");
        }

        SpecCaptcha captcha = new SpecCaptcha();
        String captchaText = captcha.text();
        redisTemplate.opsForValue().set(LOGIN_CAPTCHA_REDIS_PREFIX + key, captchaText, 5, TimeUnit.MINUTES);
        executorService.execute(() -> {
            boolean res = mailService.sendCaptcha(captchaText, key);
            if (res) {
                log.info("验证码邮件已发送,验证码:{},收件人:{}", captchaText, key);
            } else {
                log.info("验证码邮件发送失败,验证码:{},收件人:{}", captchaText, key);
            }
        });
        return RespBeanFactory.success("验证码发送成功");

    }

    /**
     * 判断是否可以拿到验证码
     */
    private boolean canGetCaptcha(String key) {
        Boolean res = redisTemplate.opsForValue().setIfAbsent(LOGIN_CAPTCHA_LIMIT_REDIS_PREFIX + key, "ok", 1, TimeUnit.MINUTES);
        if (res == null) {
            res = false;
        }
        return res;
    }

}
